package com.itts.middle.config;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.*;

/**
 * @ClassName JwtUtils
 * @Description
 * @Author zslme
 * @Date2020/3/5 8:32
 **/
public class JwtUtils {

    //秘钥
    public static final String SECRET = "zslme";
    //过期时间
    public static final int EXPIRE = 24;


    /**
     * 由字符串生成加密key
     */
    public static SecretKey generateKey(String secretKey) {
        Charset charset = Charset.forName("utf-8");
        Base64.Encoder encoder = Base64.getEncoder();
        byte[] encodedKey = encoder.encode(secretKey.getBytes(charset));
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");// 根据给定的字节数组使用AES加密算法构造一个密钥，使用 encodedKey中的始于且包含 0 到前 leng 个字节。
        return key;
    }

    /**
     * 生成jwt token
     * @param applicationId 应用ID
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String createToken(String applicationId) throws UnsupportedEncodingException {
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.HOUR, EXPIRE);
        Date expireDate = nowTime.getTime();

        Map<String, Object> map = new HashMap<>();
        map.put("alg", "HS256");
        map.put("type", "JWT");
        String token = JWT.create()
                .withHeader(map)//头
                .withClaim("applicationId", applicationId)
                .withIssuedAt(new Date())//签名时间
                .withExpiresAt(expireDate)//过期时间
                .sign(Algorithm.HMAC256(SECRET));//签名
        return token;
    }

    /*
     * 验证token
     * */
    public static Map<String, Claim> verifyToken(String token) throws Exception {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT jwt = null;
        try {
            jwt = verifier.verify(token);
        } catch (Exception e) {
            throw new Exception("token过期，请重新登陆");
        }
        return jwt.getClaims();
    }

    /*
     * 解析token
     * */
    public static Map<String, Claim> parseToken(String token) {
        DecodedJWT jwt = JWT.decode(token);
        return jwt.getClaims();
    }
}
